#include "imglib/winimage.h"

namespace img {

void DrawPackedBitmap(HDC hDC, int xd, int yd, int wd, int hd, int xs, int ys,
	size_type bit_count, size_type w, size_type h, order_type order, const void * bits)
{
	BITMAPINFO info;
	BITMAPINFOHEADER & header = info.bmiHeader;

	unsigned int scan_count = h;

	ys = h - hd - ys;
	if (order == top_down) {
		h = size_type(-(int)h);
	}

	memset(&header, 0, sizeof(BITMAPINFOHEADER));
	header.biSize			= sizeof(BITMAPINFOHEADER); 
	header.biWidth			= w; 
	header.biHeight			= h;
	header.biPlanes			= 1; 
	header.biBitCount		= bit_count; 
	header.biCompression	= BI_RGB; 
	
	SetDIBitsToDevice(hDC, xd, yd, wd, hd, xs, ys, 0, scan_count, bits, &info, DIB_RGB_COLORS);
}

void StretchPackedBitmap(HDC hDC, int xd, int yd, int wd, int hd, int xs, int ys, int ws, int hs, 
	size_type bit_count, size_type w, size_type h, order_type order, const void * bits, long ROP)
{
	BITMAPINFO info;
	BITMAPINFOHEADER & header = info.bmiHeader;

	ys = h - hs - ys;
	if (order == top_down) {
		h = size_type(-(int)h);
	}

	memset(&header, 0, sizeof(BITMAPINFOHEADER));
	header.biSize			= sizeof(BITMAPINFOHEADER); 
	header.biWidth			= w; 
	header.biHeight			= h;
	header.biPlanes			= 1; 
	header.biBitCount		= bit_count; 
	header.biCompression	= BI_RGB; 
	
	StretchDIBits(hDC, xd, yd, wd, hd, xs, ys, ws, hs, bits, &info, DIB_RGB_COLORS, ROP);
}


void DrawImage(HDC hDC, int xd, int yd, int wd, int hd, int xs, int ys, const image< BGRA<unsigned char> > & src) {

	if ((src.scansize() % 4) != 0) { // data is not aligned properly

		image< BGRA<unsigned char> > tmp;
		tmp.order(src.order());
		tmp.resize(src.width(), src.height(), 4);
		tmp = src;
		DrawPackedBitmap(hDC, xd, yd, wd, hd, xs, ys, 32, tmp.width(), tmp.height(), tmp.order(), tmp.data());

	} else {

		DrawPackedBitmap(hDC, xd, yd, wd, hd, xs, ys, 32, src.width(), src.height(), src.order(), src.data());
	}
}

void DrawImage(HDC hDC, int xd, int yd, int wd, int hd, int xs, int ys, const image< BGR<unsigned char> > & src) {

	if ((src.scansize() % 4) != 0) { // data is not aligned properly

		image< BGR<unsigned char> > tmp;
		tmp.order(src.order());
		tmp.resize(src.width(), src.height(), 4);
		tmp = src;
		DrawPackedBitmap(hDC, xd, yd, wd, hd, xs, ys, 24, tmp.width(), tmp.height(), tmp.order(), tmp.data());

	} else {

		DrawPackedBitmap(hDC, xd, yd, wd, hd, xs, ys, 24, src.width(), src.height(), src.order(), src.data());
	}
}

void StretchImage(HDC hDC, int xd, int yd, int wd, int hd, int xs, int ys, int ws, int hs, const image< BGRA<unsigned char> > & src, long ROP) {

	if ((src.scansize() % 4) != 0) { // data is not aligned properly

		image< BGRA<unsigned char> > tmp;
		tmp.order(src.order());
		tmp.resize(src.width(), src.height(), 4);
		tmp = src;
		StretchPackedBitmap(hDC, xd, yd, wd, hd, xs, ys, ws, hs, 32, tmp.width(), tmp.height(), tmp.order(), tmp.data(), ROP);

	} else {

		StretchPackedBitmap(hDC, xd, yd, wd, hd, xs, ys, ws, hs, 32, src.width(), src.height(), src.order(), src.data(), ROP);
	}
}


void StretchImage(HDC hDC, int xd, int yd, int wd, int hd, int xs, int ys, int ws, int hs, const image< BGR<unsigned char> > & src, long ROP) {

	if ((src.scansize() % 4) != 0) { // data is not aligned properly

		image< BGR<unsigned char> > tmp;
		tmp.order(src.order());
		tmp.resize(src.width(), src.height(), 4);
		tmp = src;
		StretchPackedBitmap(hDC, xd, yd, wd, hd, xs, ys, ws, hs, 24, tmp.width(), tmp.height(), tmp.order(), tmp.data(), ROP);

	} else {

		StretchPackedBitmap(hDC, xd, yd, wd, hd, xs, ys, ws, hs, 24, src.width(), src.height(), src.order(), src.data(), ROP);
	}
}

} // img
